from collections import Counter
from math import log
from selenium import webdriver
from selenium.webdriver import ChromeOptions
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from PIL import Image
import time
import random
option = webdriver.ChromeOptions()
# 添加启动参数 (add_argument)
option.add_argument('disable-infobars')  # 禁用浏览器正在被自动化程序控制的提示
option.add_experimental_option('useAutomationExtension', False)
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})

driver = webdriver.Chrome(chrome_options=option)

# 获取完整图片
def get_img1(driver):
    time.sleep(0.2)
    js_code = """
        var x = document.getElementsByClassName('gt_box')[0].style.display="block";
        console.log(x)
    """

    # 执行js代码
    driver.execute_script(js_code)
    time.sleep(1)
    driver.find_element_by_class_name('gt_box').screenshot('snap.png')
    return Image.open('snap.png')

# 获取有缺口的图片
def get_img2(driver):
    time.sleep(0.2)
    #点击拖动按钮显示缺口图片
    driver.find_element_by_xpath('//*[@class="gt_slider_knob gt_show"]').click()
    time.sleep(3.5)
    # js_code = """
    #     var x = document.getElementsByClassName("gt_slice gt_show")[0].style.display="none";
    #     console.log(x)
    # """
    # # 执行js代码
    # driver.execute_script(js_code)
    # 截取图片
    driver.find_element_by_class_name('gt_box').screenshot('snap_1.png')
    # 还原显示拖动滑块
    driver.execute_script('document.getElementsByClassName("gt_slice gt_show")[0].style.display="block"')
    return Image.open('snap_1.png')


#计算验证图片左边边界到缺口左边边界的距离（即滑块拖动距离）

def get_distance(captcha1,captcha2):  # 计算距离
    left = 60  # 这个是去掉开始的一部分
    for i in range(left, captcha1.size[0]):
        for j in range(captcha1.size[1]):
            # 判断两个像素点是否相同
            pixel1 = captcha1.load()[i, j]
            pixel2 = captcha2.load()[i, j]
            threshold = 60
            if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs(
                    pixel1[2] - pixel2[2]) < threshold:
                pass
            else:
                left = i
    return left - 55

def get_track(distance):
    """
    根据偏移量获取移动轨迹
    :param distance: 偏移量
    :return: 移动轨迹
    """
    # 移动轨迹
    track = []
    # 当前位移
    current = 0
    # 减速阈值
    mid = distance * 2 / 5
    # 计算间隔
    t = 0.3
    # 初速度
    v = 1
 
    while current < distance:
        if current < mid:
            # 加速度为正2
            a = 20
        else:
            # 加速度为负3
            a = -2
        # 初速度v0
        v0 = v
        # 当前速度v = v0 + at
        v = v0 + a * t
        # 移动距离x = v0t + 1/2 * a * t^2
        move = v0 * t + 1 / 2 * a * t * t
        # 当前位移
        current += move
        # 加入轨迹
        track.append(round(move))
    return track 

def move_to_track(driver,distance):
    stacks = get_track(distance)
    slider_btn = driver.find_element_by_xpath('//*[@class="gt_slider_knob gt_show"]')
    time.sleep(0.2)
    ActionChains(driver).click_and_hold(slider_btn).perform()
    time.sleep(0.2)
    for forward_stack in stacks:
        ActionChains(driver).move_by_offset(xoffset=forward_stack, yoffset=0).perform()
        ActionChains(driver).pause(__getRadomPauseScondes())
    ActionChains(driver).move_by_offset(xoffset=1, yoffset=0).perform()
    ActionChains(driver).move_by_offset(xoffset=-1, yoffset=0).perform()
    # for back_stack in back_stacks:
    #     ActionChains(driver).move_by_offset(xoffset=back_stack, yoffset=0).perform()
    #     time.sleep(0.1)

    time.sleep(0.5)
    ActionChains(driver).release().perform()

def __getRadomPauseScondes():
        """
        :return:随机的拖动暂停时间
        """
        return random.uniform(0.6, 0.9)

def verify(driver):
    img1 = get_img1(driver)
    img2 = get_img2(driver)
    distance = get_distance(img1,img2)
    move_to_track(driver,distance)
    time.sleep(3.5)

def login():
    driver.get('https://www.tianyancha.com') 
    time.sleep(1.5)
    driver.find_element_by_xpath('//*[@class="link-white"]').click()
    driver.implicitly_wait(2)
    sign = driver.find_element_by_class_name('sign-in')
    # 点击切换密码登录
    sign.find_element_by_xpath('./div[1]/div[2]').click()
    driver.implicitly_wait(1)
    # 步骤一：找到输入账户框
    user_input = driver.find_element_by_id('mobile')

    # 步骤二：找到输入密码框
    pwd_input = driver.find_element_by_id('password')

    user_input.send_keys('15288635003')
    driver.implicitly_wait(1)
    pwd_input.send_keys('wjs19960722')
    # 步骤三：找到确认登录按钮,并点击
    time.sleep(2)
    login_btn = driver.find_element_by_xpath('//*[@class="btn -xl btn-primary -block"]')
    time.sleep(2)
    login_btn.click()
    time.sleep(2)

if __name__ == '__main__':
    try:
       
        login()
        # 验证  
        verify(driver)
        while(True):
            try:
                driver.find_element_by_xpath('//*[@class="nav-user-name"]')
                break
            except Exception as e:
                # driver.find_element_by_xpath('//*[@class="gt_refresh_button"]').click()
                driver.refresh()
                login()
                time.sleep(0.5)
                verify(driver)

        driver.get("https://www.tianyancha.com/advance/search/e-pc_homeicon")
    finally:
        # driver.quit()
        pass